using AutoMapper;
using Azure.Core;
using Process.Api.DTO.InputDTO;
using Process.Domain.DTO.InputDTO;
using Process.Domain.DTO.OutDTO;
using Process.Domain.Entities;
using Process.Infrastructure.Repositories;
using Process.Result;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text.Json;

namespace Process.Application.Services
{
    public class ProcessAppService<T> : IProcessAppService<T> where T:BaseEntity
    {
        private readonly IProcessRepository<ProcessModel> _repository;
        private readonly IMapper _mapper;
        
        public ProcessAppService(
            IProcessRepository<ProcessModel> repository,
            IMapper mapper)
        {
            _repository = repository;
            _mapper = mapper;
        }
        
    
        
        /// <summary>
        /// 添加工序（使用DTO）
        /// </summary>
        /// <param name="processDTO">工序数据传输对象</param>
        /// <returns>API结果</returns>
        public ApiResult<int> AddProcess(AddProcessDTO processDTO)
        {
            // 验证参数是否为空
            if (processDTO == null)
            {
                return new ApiResult<int>
                {
                    Success = ResultCode.Fail,
                    Message = "参数不能为空",
                    Data = 0
                };
            }

            try
            {
                // 使用AutoMapper将DTO映射为实体
                var processModel = _mapper.Map<ProcessModel>(processDTO);
                
                // 生成雪花ID
                processModel.Id = GenerateSnowflakeId();
                string ss = Guid.NewGuid().ToString();
                processModel.ProcessCode = ss;
                // 设置创建时间和创建人
                processModel.CreatedAt = DateTime.Now;
                processModel.CreatedBy = "System"; // 可以从认证上下文中获取当前用户
                
                // 调用仓储添加数据
                int result = _repository.Create(processModel);
                
                return new ApiResult<int>
                {
                    Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                    Message = result > 0 ? "添加成功" : "添加失败",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<int>
                {
                    Success = ResultCode.Fail,
                    Message = $"添加失败: {ex.Message}",
                    Data = 0
                };
            }
        }

        /// <summary>
        /// 删除工序
        /// </summary>
        /// <param name="processDTO"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<int> DeleteProcess(long Id)
        {
            ApiResult<int> api = new ApiResult<int>();
            var data = _repository.GetModel(Id);
            data.IsDeleted = true;
            var result= _repository.Update(data);
            return new ApiResult<int>
            {
                Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                Message = result > 0 ? "删除成功" : "删除失败",
                Data = result
            };
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns>封装响应类</returns>
        public Apipaging<PagingProcessDTO> PagingProcess(PagingProcessInput input)
        {
            Apipaging<PagingProcessDTO> api = new Apipaging<PagingProcessDTO>();
            var list = _repository.GetValue().Where(x => x.IsDeleted == false);
            if (!string.IsNullOrEmpty(input.ProcessName))
            {
                list = list.Where(x => x.ProcessName.Equals(input.ProcessName));
            }
            if (!string.IsNullOrEmpty(input.ProcessCode))
            {
                list = list.Where(x => x.ProcessCode.Equals(input.ProcessCode));
            }
            api.TotalCount = list.Count();
            api.TotalPages =(int)Math.Ceiling(api.TotalCount * 1.0 / input.PagingSize);
           var data = list.OrderBy(x => x.Id).Skip((input.PagingIndex - 1) * input.PagingSize).Take(input.PagingSize).ToList();
            api.PagingData = _mapper.Map<List<PagingProcessDTO>>(data);
                
            return api;
        }

        /// <summary>
        /// 显示工序
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Apipaging<ShowprocessDTO> ShowProcess()
        {
           Apipaging<ShowprocessDTO>  api=new Apipaging<ShowprocessDTO>();
            var data = _repository.GetValue().Where(x => x.IsDeleted == false);
            
            api.PagingData = _mapper.Map<List<ShowprocessDTO>>(data);
            return api;
        }

        /// <summary>
        /// 修改工序
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<int> UpdateProcess(UpdateProcessInput input)
        {
            ApiResult<int> api=new ApiResult<int>();
            var process = _repository.GetModel(input.Id);
            var data = _mapper.Map(input, process);
            var result = _repository.Update(data);
            return new ApiResult<int>
            {
                Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                Message = result > 0 ? "修改成功" : "修改失败",
                Data = result
            };
        }

        /// <summary>
        /// 生成雪花ID
        /// </summary>
        /// <returns>唯一ID</returns>
        private long GenerateSnowflakeId()
        {
            // 简化版雪花ID实现
            long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            long machineId = 1; // 机器ID
            long sequence = new Random().Next(0, 4095); // 序列号

            return ((timestamp - 1288834974657L) << 22) | (machineId << 12) | sequence;
        }

        /// <summary>
        /// 工艺流程排序
        /// </summary>
        /// <param name="workflow">工艺流程数据</param>
        /// <returns>排序后的工艺流程</returns>
        public ApiResult<List<StepNode>> SortProcessFlow(WorkflowSortInput workflow)
        {
            try
            {
                if (workflow == null)
                {
                    return new ApiResult<List<StepNode>>
                    {
                        Success = ResultCode.Fail,
                        Message = "工艺流程数据不能为空",
                        Data = null
                    };
                }

                // 使用工艺流程排序工具类进行排序
                List<StepNode> sortedWorkflow = ProcessFlowSorter.SortWorkflow(workflow);

                return new ApiResult<List<StepNode>>
                {
                    Success = ResultCode.Success,
                    Message = "工艺流程排序成功",
                    Data = sortedWorkflow
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<List<StepNode>>
                {
                    Success = ResultCode.Fail,
                    Message = $"工艺流程排序失败: {ex.Message}",
                    Data = null
                };
            }
        }

      public  List<StepNode> SortProcessFlow22(WorkflowSortInput workflow)
        {
            if (workflow == null || workflow.nodes == null || workflow.connections == null)
            {
                throw new ArgumentNullException("工艺流程数据不完整");
            }

            // 构建图结构（邻接表）
            Dictionary<string, List<string>> graph = new Dictionary<string, List<string>>();
            foreach (var node in workflow.nodes)
            {
                graph[node.id] = new List<string>();
            }

            foreach (var connection in workflow.connections)
            {
                if (graph.ContainsKey(connection.source))
                {
                    graph[connection.source].Add(connection.target);
                }
            }

            // 使用BFS进行拓扑排序
            List<WorkflowNode> sortedNodes = new List<WorkflowNode>();
            HashSet<string> visited = new HashSet<string>();
            Queue<string> queue = new Queue<string>();

            // 查找开始节点（类型为start的节点）
            var startNode = workflow.nodes.FirstOrDefault(n => n.type.ToLower() == "start");
            if (startNode == null)
            {
                throw new InvalidOperationException("找不到开始节点");
            }

            // 从开始节点开始排序
            queue.Enqueue(startNode.id);
            visited.Add(startNode.id);

            while (queue.Count > 0)
            {
                string currentId = queue.Dequeue();

                // 添加当前节点到结果列表
                var currentNode = workflow.nodes.FirstOrDefault(n => n.id == currentId);
                if (currentNode != null)
                {
                    sortedNodes.Add(currentNode);
                }

                // 遍历所有连接的节点
                if (graph.ContainsKey(currentId))
                {
                    foreach (var nextId in graph[currentId])
                    {
                        if (!visited.Contains(nextId))
                        {
                            visited.Add(nextId);
                            queue.Enqueue(nextId);
                        }
                    }
                }
            }

            // 检查是否所有节点都已访问
            if (visited.Count != workflow.nodes.Count())
            {
                // 有些节点未被访问到，可能是工艺流程中存在孤立节点或循环
                var unvisitedNodes = workflow.nodes.Where(n => !visited.Contains(n.id)).ToList();
                foreach (var node in unvisitedNodes)
                {
                    sortedNodes.Add(node); // 将未访问的节点添加到最后
                }
            }

            // 将排序后的节点转换为StepNode格式
            List<StepNode> stepNodes = new List<StepNode>();

            // 创建节点映射，用于设置StepNextId
            Dictionary<string, string> nodeIdToStepIdMap = new Dictionary<string, string>();
            foreach (var node in sortedNodes)
            {
                // 使用processId作为StepId，如果为空则使用节点Id
                string stepId = !string.IsNullOrEmpty(node.processId) ? node.processId : node.id;
                nodeIdToStepIdMap[node.id] = stepId;
            }

            // 创建StepNode列表
            for (int i = 0; i < sortedNodes.Count; i++)
            {
                var currentNode = sortedNodes[i];

                // 获取当前节点的StepId
                string stepId = nodeIdToStepIdMap[currentNode.id];

                // 确定下一个节点的StepId
                string nextStepId = "";
                if (i < sortedNodes.Count - 1 && currentNode.type.ToLower() != "end")
                {
                    // 获取图中的下一个节点
                    var connections = graph[currentNode.id];
                    if (connections.Count > 0)
                    {
                        string nextNodeId = connections[0];
                        nextStepId = nodeIdToStepIdMap[nextNodeId];

                        // 如果下一个节点是end节点，则StepNextId为空
                        var nextNode = workflow.nodes.FirstOrDefault(n => n.id == nextNodeId);
                        if (nextNode != null && nextNode.type.ToLower() == "end")
                        {
                            nextStepId = "";
                        }
                    }
                }

                // 解析审核人ID
                long auditUserId = 0;
                if (!string.IsNullOrEmpty(currentNode.approver))
                {
                    long.TryParse(currentNode.approver, out auditUserId);
                }

                // 创建StepNode
                var stepNode = new StepNode
                {
                    StepId = stepId,
                    StepName = currentNode.name,
                    StepNextId = nextStepId,
                    AuditUserId = auditUserId,
                    AuditUserName = currentNode.approverName ?? ""
                };

                stepNodes.Add(stepNode);
            }

            return stepNodes;
        }
    }
} 